package com.exam.api.config;

import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.spring.SaBeanInject;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.exam.api.common.utils.StpManagerUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.boot.LazyInitializationExcludeFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


/**
 * @Author bcheng
 * @Create 2024/1/13 12:09
 * @Description SaToken配置类
 */
@Slf4j
@Configuration
public class SaTokenConfig implements WebMvcConfigurer {
    @Bean
    LazyInitializationExcludeFilter integrationLazyInitExcludeFilter() {
        return LazyInitializationExcludeFilter.forBeanTypes(SaBeanInject.class);
    }

    /**
     * 注册sa-token的拦截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册路由拦截器，自定义验证规则
        registry.addInterceptor(new SaInterceptorWrapper()).addPathPatterns("/**");
    }

    /**
     * @Author 北橙
     * @Create 2023/5/26
     * @Description SaInterceptor 包装类
     * @Version 1.0
     */
    @Slf4j
    public static class SaInterceptorWrapper extends SaInterceptor {

        public static final String MDC_USER_ID_KEY = "UserId";

        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            try {
                // 获取当前登录用户id
                String userId = StpUtil.getLoginId(StpManagerUtil.getLoginId(StrUtil.EMPTY));
                if (StrUtil.isEmpty(userId)) {
                    // 从请求头中获取用户id
                    userId = request.getHeader(MDC_USER_ID_KEY);
                }
                if (StrUtil.isEmpty(userId)) {
                    userId = "Ignored_User";
                }
                if (StrUtil.isNotEmpty(userId)) {
                    MDC.put(MDC_USER_ID_KEY, userId);
                }
            } catch (Exception e) {
                log.error(" <<<=== SaInterceptorWrapper.preHandle Exception : ", e);
            }
            return super.preHandle(request, response, handler);
        }

        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            try {
                super.postHandle(request, response, handler, modelAndView);
            } finally {
                MDC.remove(MDC_USER_ID_KEY);
            }
        }
    }
}
